#include <stdio.h>
#include <stdlib.h>
//栈之链栈
typedef int ElemType;
//声明
typedef struct stack
{
    ElemType data;
    struct stack *next;
}Stack;
//初始化
Stack *initstack()
{
    Stack *s=(Stack *)malloc(sizeof(Stack));
    s->data=0;
    s->next=NULL;
    return s;
}
//入栈
void push(Stack *s,ElemType n)
{
    Stack *p=(Stack *)malloc(sizeof(Stack)); //先创建一个新节点
    p->data=n;
    p->next=s->next;
    s->next=p;
}
//打印
int printstack(Stack *s)
{
    if(s->next==NULL)
    {
        printf("空栈\n");
        return 0;
    }
    else
    {
        Stack *p=s->next;
        while(p)
        {
            printf("%d ",p->data);
            p=p->next;
        }
        printf("\n");
        return 1;
    }
}
//出栈
int pop(Stack *s,ElemType *ret)
{
    if(s->next==NULL)
    {
        printf("空栈\n");
        return 0;
    }
    else
    {
        *ret=s->next->data;
        Stack *p=s->next;
        s->next=p->next;
        free(p);
        return 1;
    }
}
//获取个数(头节点不算)
int shu(Stack *s)
{
    Stack*p=s->next;
    int l=0;
    while(p)
    {
        l++;
        p=p->next;
    }
    return l;
}
//释放
void freestack(Stack *s)
{
    Stack *p=s;
    Stack *q;
    while(p)
    {
        q=p->next;
        free(p);
        p=q;
    }
}
int main()
{
    Stack *s=initstack();
    //入栈（压栈）：先进后出，所以用头插法，先往里压的是栈底
    //因为单链表遍历是从头到尾，先访问（出栈）的元素靠近头节点，即首元节点就是栈顶元素
    push(s,22);
    push(s,52);
    push(s,66);
    push(s,88);
    //打印
    printstack(s);
    //出栈
    ElemType ret=0;
    pop(s,&ret);
    printf("出栈数据是%d\n",ret);
    //获取个数
    int sum=shu(s);
    printf("元素有%d个\n",sum);
    //释放
    freestack(s);
    return 0;
}